import { Inject, Injectable, forwardRef } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { Budget } from 'src/entity/Budget'
import { Connection, IsNull, Repository } from 'typeorm'
import { v4 as uuidV4 } from 'uuid'
import { Not } from 'typeorm'
import { TaskService } from 'src/task/task.service'
import { Task } from 'src/entity/Task'

@Injectable()
export class BudgetService {
  constructor(
    @InjectRepository(Budget)
    private budgetRepository: Repository<Budget>,
    @Inject(forwardRef(() => TaskService))
    private readonly taskService: TaskService,
    private connection: Connection,
  ) { }

  async add(data) {
    const budgetCode = 'B-' + uuidV4()
    await this.connection.transaction(async (manager) => {
      const sqlData = await this.budgetRepository.save(
        Object.assign({}, data, {
          budgetCode,
          receiveType: '0',
        }),
      )
      const taskData = new Task()
      taskData.receiveBranch = sqlData.receiveBranch
      taskData.receiveBranchId = sqlData.receiveBranchId
      taskData.receivePerson = sqlData.receivePerson
      taskData.receivePersonId = sqlData.receivePersonId
      taskData.receiveCode = sqlData.budgetCode
      taskData.receiveDate = sqlData.receiveDate
      taskData.taskName = sqlData.budgetName
      taskData.taskStatus = sqlData.receiveType
      taskData.taskType = '0'
      await this.taskService.add(taskData)
    })

    return data
  }

  async del(id: number) {
    let data
    await this.connection.transaction(async (manager) => {
      const sqlData = await this.budgetRepository.findOne({
        where: {
          id,
        },
      })
      await this.taskService.delByCode(sqlData.budgetCode)
      data = await manager.update(
        Budget,
        {
          id: id,
        },
        {
          isDelete: true,
        },
      )
    })
    return data
  }

  async update(data) {
    data.receiveType = '0'
    data.reason = null
    let sqlData
    await this.connection.transaction(async (manager) => {
      await this.taskService.updateProperty(
        data.budgetCode,
        'taskStatus',
        data.receiveType,
      )
      await this.taskService.updateProperty(data.budgetCode, 'reason', null)
      await this.taskService.updateProperty(data.budgetCode, 'taskDate', null)
      await this.taskService.updateProperty(
        data.budgetCode,
        'taskPersonId',
        null,
      )
      await this.taskService.updateProperty(data.budgetCode, 'taskPerson', null)
      sqlData = await this.budgetRepository.update(
        {
          id: data.id,
        },
        data,
      )
    })
    return sqlData
  }

  // 分页查询
  async getPageList({
    pageRequest: { pageIndex, pageSize },
    budgetCode,
    budgetName,
    receivePerson,
    receiveBranch,
    receiveType,
    orgId,
  }) {
    const sqlAllData = await this.budgetRepository.find({
      where: {
        isDelete: IsNull(),
        receiveBranchId: orgId,
        budgetCode: budgetCode,
        budgetName: budgetName,
        receivePerson: receivePerson,
        receiveBranch: receiveBranch,
        receiveType: receiveType,
      },
    })
    const sqlData = await this.budgetRepository.find({
      where: {
        isDelete: IsNull(),
        receiveBranchId: orgId,
        budgetCode: budgetCode,
        budgetName: budgetName,
        receivePerson: receivePerson,
        receiveBranch: receiveBranch,
        receiveType: receiveType,
      },
      skip: (pageIndex - 1) * pageSize,
      take: pageSize,
      withDeleted: false,
    })

    return {
      content: sqlData,
      total: sqlAllData.length,
    }
  }

  // 获取预算列表
  async getBudgetList(isUse = false, orgId: number) {
    const sqlDataList = await this.budgetRepository.find({
      where: isUse
        ? {
          isDelete: IsNull(),
          isUse: IsNull(),
          receiveBranchId: orgId,
          receiveType: '2',
        }
        : {
          isDelete: IsNull(),
          receiveBranchId: orgId,
          receiveType: '2',
        },
    })
    return sqlDataList.map((item) => {
      return {
        label: item.budgetName,
        value: item.id.toString(),
      }
    })
  }

  // 更新某个属性
  async updateProperty(code, property, value) {
    return await this.budgetRepository.update(
      {
        budgetCode: code,
      },
      {
        [property]: value,
      },
    )
  }

  // 获取预算详情 budgetCode -> *
  async getDetailByCode(code) {
    return await this.budgetRepository.findOne({
      where: {
        budgetCode: code,
        isDelete: IsNull(),
      },
    })
  }
}
